package com.xxxtea.service;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import java.io.Serializable;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 基础服务类
 * 
 * 该抽象类为所有业务服务提供通用的基础功能，继承自MyBatis-Plus的ServiceImpl。
 * 提供了常用的数据查询和操作方法，减少重复代码的编写。
 * 
 * @param <M> Mapper类型，必须继承BaseMapper
 * @param <T> 实体类型
 * @author badman
 * @since 1.0.0
 */
public abstract class BaseService<M extends BaseMapper<T>, T> extends ServiceImpl<M, T> {
	
	/**
	 * 默认构造函数
	 */
	public BaseService() {
	}

	/**
	 * 根据ID列表批量查询实体
	 * 
	 * 重写父类方法，增加了空值检查，避免传入空集合时出现异常
	 * 
	 * @param idList ID集合
	 * @return 实体列表，如果ID集合为空则返回空列表
	 */
	@Override
	public List<T> listByIds(Collection<? extends Serializable> idList) {
		// 检查ID集合是否为空
		if (CollUtil.isEmpty(idList)) {
			return new ArrayList<>();
		}
		// 调用父类方法进行批量查询
		return super.listByIds(idList);
	}

	/**
	 * 根据指定字段值查询实体列表
	 * 
	 * 使用Lambda表达式构建查询条件，提供类型安全的字段查询
	 * 
	 * @param function 字段函数，如 User::getName
	 * @param value 字段值
	 * @param <V> 字段值类型
	 * @return 匹配的实体列表
	 */
	public <V> List<T> listByField(SFunction<T, V> function, V value) {
		return this.lambdaQuery().eq(function, value).list();
	}

	/**
	 * 根据ID列表批量查询实体并转换为Map
	 * 
	 * 将查询结果转换为以ID为key的Map结构，便于快速查找
	 * 
	 * @param ids ID列表
	 * @param keyMapper 从实体中提取key的函数
	 * @param <ID> ID类型
	 * @return 以ID为key的实体Map，如果ID列表为空则返回空Map
	 */
	public <ID extends Serializable> Map<ID, T> getMapByIds(List<ID> ids, Function<T, ID> keyMapper) {
		// 检查ID列表是否为空
		if (CollUtil.isEmpty(ids)) {
			return new HashMap<>();
		}
		// 批量查询实体
		List<T> list = this.listByIds(ids);
		// 转换为Map结构
		return list.stream().collect(Collectors.toMap(keyMapper, Function.identity()));
	}
}